package com.ntv.persistent.user;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;

import com.ntv.domain.IUser;
import com.ntv.persistent.AbstractDao;
import com.ntv.persistent.PersistentException;

/**
 * @author Vedamoorthi Vairam
 * @since 05/01/2009
 *
 */
public class SqlUserDao  extends AbstractDao implements IUserDao 
{
	interface CONST 
	{
		interface QUERY 
		{
			final String FIND_USER_BY_ID = "SELECT id, fname, mname, lname, email, password, question," +
			"answer, dob, gender, created_by, updated_by, created_on, udated_on from user  where id:ID";	
	
			final String FIND_USER_BY_NAME = "SELECT id, fname, mname, lname, email, password, question," +
				"answer, dob, gender, created_by, updated_by, created_on, udated_on where from user  name=:NAME";
	
			final String FIND_USER_BY_EMAIL= "SELECT id, fname, mname, lname, email, password, question," +
			"answer, dob, gender, created_by, updated_by, created_on, udated_on from user  where email=:EMAIL";
			
			final String FIND_USER_BY_EMAIL_PASSWORD = "SELECT id, fname, mname, lname, email, password, question," +
			"answer, dob, gender, created_by, updated_by, created_on, udated_on from user where email=:email and password=:password";
			
			
			final String CREATE_USER = " insert into user" +
					"(id, fname, mname,	lname, " +
					" email, password, question, answer," +
					" dob, gender,	created_by,	updated_by,	created_on,	udated_on)" +
					" values" +
					" ('id','fname', 'mname'," +
					" 'lname',	'email', 'password'," +
					" 'question', 'answer',	'dob'," +
					" 'gender',	'created_by',	'updated_by'," +
					" 'created_on',	'udated_on'	)";
		}
	}
	
	private SimpleJdbcInsert insertUser;
	
	public List<IUser> getUsers() throws PersistentException 
	{
		return null;
	}
	
	public IUser findUserByID(Long userId) throws PersistentException 
	{
		SqlParameterSource namedParameters = new MapSqlParameterSource("ID", userId);
		try 
		{
			return (IUser) getNamedParameterJdbcTemplate().queryForObject(
					CONST.QUERY.FIND_USER_BY_ID, namedParameters, getRowMapper());
		}
		catch (DataAccessException e) 
		{
			throw new PersistentException(e);
		}
	}
	
	public IUser findUserByName(String name) throws PersistentException 
	{
		SqlParameterSource namedParameters = new MapSqlParameterSource("NAME", name);
		try 
		{
			return (IUser)getNamedParameterJdbcTemplate().queryForObject(CONST.QUERY.FIND_USER_BY_NAME, namedParameters, getRowMapper());
		}
		catch (EmptyResultDataAccessException ex) {
			return null;
		}
		catch (DataAccessException e) 
		{
			throw new PersistentException(e);
		}
	}
	
	public IUser findUserByEmail(String email) throws PersistentException 
	{
		SqlParameterSource namedParameters = new MapSqlParameterSource("EMAIL", email);
		try 
		{
			return (IUser)getNamedParameterJdbcTemplate().queryForObject(CONST.QUERY.FIND_USER_BY_EMAIL, namedParameters, getRowMapper());
		}
		catch (EmptyResultDataAccessException ex) {
			return null;
		}
		catch (DataAccessException e) 
		{
			throw new PersistentException(e);
		}
	}
	
//	private static final Logger logger = Logger.getLogger(SqlUserDao.class);
	public IUser findUser(String email, String password) throws PersistentException {
		try 
		{
			Map param = new HashMap();
			param.put("email", email);
			param.put("password", password);
			SqlParameterSource namedParameters 
								= new MapSqlParameterSource(param);
			
			IUser user = (IUser) getNamedParameterJdbcTemplate()
							.queryForObject(CONST.QUERY.FIND_USER_BY_EMAIL_PASSWORD, 
							namedParameters,
							getRowMapper());
			
			return (IUser) getNamedParameterJdbcTemplate()
				.queryForObject(CONST.QUERY.FIND_USER_BY_EMAIL_PASSWORD, 
								namedParameters,
								getRowMapper());
//			logger.info(user.getId());
//			logger.info(user.getFname());
//			logger.info(user.getLname());
//			logger.info(user.getEmail());
//			logger.info(user.getPassword());
//			logger.info(user.getQuestion());
//			logger.info(user.getAnswer());
//			logger.info(user.getDob());
//			logger.info(user.getGender());
//			logger.info(user.getCreatedBy());
//			logger.info(user.getUpdatedBy());
//			logger.info(user.getDateOfCreation());
//			logger.info(user.getDateOfUpdate());
//			logger.info(user.getPasswordConfirmation());
//			logger.info(user.isAcceptTerms());
//			return user;
		}
		catch (EmptyResultDataAccessException ex) {
			return null;
		}
		catch (DataAccessException ex)
		{
			throw new PersistentException(ex);
		}
	}
	
	public IUser createUser(IUser user)  throws PersistentException {
		try {			
		insertUser = new SimpleJdbcInsert(getJdbcTemplate())
			.withTableName(getTableName())			
			.usingGeneratedKeyColumns("id");
		
		Map<String, Object> parameters = new HashMap<String, Object>(10);
		parameters.put("fname", user.getFname());
		parameters.put("lname", user.getLname());
		parameters.put("email", user.getEmail());
		parameters.put("password", user.getPassword());		
		parameters.put("created_by", user.getCreatedBy() == null ? 0 : user.getCreatedBy());
		parameters.put("updated_by", user.getUpdatedBy() == null ? 0 : user.getUpdatedBy());
		parameters.put("created_on", new Date());
		parameters.put("udated_on", new Date());
		
		Number newId = insertUser.executeAndReturnKey(parameters);
		user.setId(newId.longValue());
		
		return user;
		}catch (DataAccessException ex) {
			throw new PersistentException(ex);
		}
	}
}
